package com.cfweb.controller.system;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cfweb.api.OrgApi;
import com.cfweb.api.UserApi;
import com.cfweb.controller.LoginHandler;
import com.cfweb.dao.AppTemplateMapper;
import com.cfweb.dao.AuthUserMapper;
import com.cfweb.dao.CfAppMapper;
import com.cfweb.dao.CfServiceInstanceMapper;
import com.cfweb.dao.CfUserMapper;
import com.cfweb.domain.AppTemplate;
import com.cfweb.domain.AppTemplateExample;
import com.cfweb.domain.AuthUser;
import com.cfweb.domain.AuthUserExample;
import com.cfweb.domain.CfApp;
import com.cfweb.domain.CfAppExample;
import com.cfweb.domain.CfServiceInstance;
import com.cfweb.domain.CfServiceInstanceExample;
import com.cfweb.domain.CfUser;
import com.cfweb.domain.CfUserExample;
import com.cfweb.util.ExtJSResponse;
import com.cfweb.util.StringUtil;

/**
 * 
 * @author dt
 *
 */
@Service
@Path("/org")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class OrgManagement {
	
	Logger logger = Logger.getLogger(OrgManagement.class);
	
	@Autowired  
	private HttpSession session; 
	@Autowired
	private AuthUserMapper auMapper;
	@Autowired
	private CfUserMapper cuMapper;
	
	@Autowired
	private AppTemplateMapper apptemMapper;
	@Autowired
	private CfAppMapper cfappMapper;
	
	@Autowired
	private CfServiceInstanceMapper cfserinsMapper;
	
	
	/**
     * list all of Organization
     * @param 无
     * @return list
     */
	@Path("/listall")
	@GET
	public ExtJSResponse listall() {
		List<Map<String, Object>> orgs = null;
		try {
			orgs = OrgApi.list_orgs(session);
		} catch(Exception e) {
			logger.error(e);
			return ExtJSResponse.errorRes();
		}
		return ExtJSResponse.successResWithData(orgs);
	}
	
	//the information of quota is only available using orgName
	/**
     * list org by orgName
     * @param orgName
     * @return org
     */
	@Path("/list")
	@GET
	public ExtJSResponse list(@QueryParam("orgName") String orgName) {
		List<Map<String, Object>> org = null;
		try {
			org = OrgApi.list_org(session, orgName);
		} catch(Exception e) {
			logger.error(e);
			return ExtJSResponse.errorRes();
		}
		return ExtJSResponse.successResWithData(org);
	}
	
	/**
     * add an org
     * @param orgName
     * @return success or error
     */
	@Path("/add")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse add(@FormParam("orgName") String orgName,@FormParam("quotaId") String quota) throws Exception {
		if (OrgApi.create_org(session, orgName,quota)) {
		    return ExtJSResponse.successRes();
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * delete an org
     * @param orgName
     * @return success or error
     */
	@Path("/delete")
	@GET
	public ExtJSResponse delete(@QueryParam("orgName") String orgName) throws Exception {
		if (OrgApi.delete_org(session, orgName)) {
			AuthUserExample auEx = new AuthUserExample();
			auEx.createCriteria().andOrgNameEqualTo(orgName);			
			auMapper.deleteByExample(auEx);
			CfUserExample cuEx = new CfUserExample();
			cuEx.createCriteria().andLastOrgEqualTo(orgName);
			List<CfUser> culist = cuMapper.selectByExample(cuEx);
			AppTemplateExample apptemEx = new AppTemplateExample();
			apptemEx.createCriteria().andOrgEqualTo(orgName);
			apptemMapper.deleteByExample(apptemEx);
			CfAppExample cfappEx = new CfAppExample();
			cfappEx.createCriteria().andOrgEqualTo(orgName);
			cfappMapper.deleteByExample(cfappEx);
			CfServiceInstanceExample cfserInsEx = new CfServiceInstanceExample();
			cfserInsEx.createCriteria().andOrgEqualTo(orgName);
			cfserinsMapper.deleteByExample(cfserInsEx);
			if(culist.size() != 0) {
				for(CfUser cu:culist) {
					cu.setLastOrg(null);
					cu.setLastSpace(null);
					cuMapper.updateByPrimaryKey(cu);
				}
			}
			if(orgName.equals(session.getAttribute(LoginHandler.ORG))) {
				session.setAttribute(LoginHandler.ORG, null);
				session.setAttribute(LoginHandler.SPACE, null);
			}
			List<String> lau = new ArrayList<String>();
			lau.add((String) session.getAttribute(LoginHandler.ORG));
			lau.add((String) session.getAttribute(LoginHandler.SPACE));
			return ExtJSResponse.successResWithData(lau);
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * rename an org
     * @param orgName
     * @param newName
     * @return success or error
     */
	@Path("/rename")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse rename(@FormParam("orgName") String orgName, 
			@FormParam("newName") String newName) throws Exception {
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName);
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andLastOrgEqualTo(orgName);
		AppTemplateExample apptemEx = new AppTemplateExample();
		apptemEx.createCriteria().andOrgEqualTo(orgName);
		CfAppExample cfappEx = new CfAppExample();
		cfappEx.createCriteria().andOrgEqualTo(orgName);
		CfServiceInstanceExample cfserIns = new CfServiceInstanceExample();
		cfserIns.createCriteria().andOrgEqualTo(orgName);
		if (OrgApi.rename_org(session, orgName, newName)) {
			if(auMapper.selectByExample(auEx).size() != 0) {
				for(AuthUser au:auMapper.selectByExample(auEx)) {
					au.setOrgName(newName);
					auMapper.updateByPrimaryKey(au);
				}
			}
			if(cuMapper.selectByExample(cuEx).size() != 0) {
				for(CfUser cu:cuMapper.selectByExample(cuEx)) {
					cu.setLastOrg(newName);
					cuMapper.updateByPrimaryKey(cu);
				}
			}
			if(orgName.equals((String) session.getAttribute(LoginHandler.ORG))) {
				session.removeAttribute(LoginHandler.ORG);
				session.setAttribute(LoginHandler.ORG, newName);
			}
			List<AppTemplate> atemlist = apptemMapper.selectByExample(apptemEx);
			if(atemlist.size() != 0) {
				for(AppTemplate atem:atemlist) {
					atem.setOrg(newName);
					apptemMapper.updateByPrimaryKey(atem);
				}
			}
			List<CfApp> cfalist = cfappMapper.selectByExample(cfappEx);
			if(cfalist.size() != 0) {
				for(CfApp cfa:cfalist) {
					cfa.setOrg(newName);
					cfappMapper.updateByPrimaryKey(cfa);
				}
			}
			List<CfServiceInstance> cfserlist = cfserinsMapper.selectByExample(cfserIns);
			if(cfserlist.size() != 0) {
				for(CfServiceInstance cfser:cfserlist) {
					cfser.setOrg(newName);
					cfserinsMapper.updateByPrimaryKey(cfser);
				}
			}
			return ExtJSResponse.successRes();
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * rename an org
     * @param orgName
     * @param newName
     * @return success or error
     */
	@Path("/update")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse update(@FormParam("orgName") String orgName, 
			@FormParam("newName") String newName,@FormParam("quotaId") String quota) throws Exception {
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andOrgNameEqualTo(orgName);
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andLastOrgEqualTo(orgName);
		AppTemplateExample apptemEx = new AppTemplateExample();
		apptemEx.createCriteria().andOrgEqualTo(orgName);
		CfAppExample cfappEx = new CfAppExample();
		cfappEx.createCriteria().andOrgEqualTo(orgName);
		CfServiceInstanceExample cfserIns = new CfServiceInstanceExample();
		cfserIns.createCriteria().andOrgEqualTo(orgName);
		if (OrgApi.update_org(session, orgName, newName,quota)) {
			if(auMapper.selectByExample(auEx).size() != 0) {
				for(AuthUser au:auMapper.selectByExample(auEx)) {
					au.setOrgName(newName);
					auMapper.updateByPrimaryKey(au);
				}
			}
			if(cuMapper.selectByExample(cuEx).size() != 0) {
				for(CfUser cu:cuMapper.selectByExample(cuEx)) {
					cu.setLastOrg(newName);
					cuMapper.updateByPrimaryKey(cu);
				}
			}
			if(orgName.equals((String) session.getAttribute(LoginHandler.ORG))) {
				session.removeAttribute(LoginHandler.ORG);
				session.setAttribute(LoginHandler.ORG, newName);
			}
			List<AppTemplate> atemlist = apptemMapper.selectByExample(apptemEx);
			if(atemlist.size() != 0) {
				for(AppTemplate atem:atemlist) {
					atem.setOrg(newName);
					apptemMapper.updateByPrimaryKey(atem);
				}
			}
			List<CfApp> cfalist = cfappMapper.selectByExample(cfappEx);
			if(cfalist.size() != 0) {
				for(CfApp cfa:cfalist) {
					cfa.setOrg(newName);
					cfappMapper.updateByPrimaryKey(cfa);
				}
			}
			List<CfServiceInstance> cfserlist = cfserinsMapper.selectByExample(cfserIns);
			if(cfserlist.size() != 0) {
				for(CfServiceInstance cfser:cfserlist) {
					cfser.setOrg(newName);
					cfserinsMapper.updateByPrimaryKey(cfser);
				}
			}
			return ExtJSResponse.successRes();
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * check an org for the exited
     * @param orgName
     * @return success or error
     */
	@Path("/checkOrgName")
	@GET
	public ExtJSResponse checkOrgName(@QueryParam("orgName") String orgName,@QueryParam("guid") String guid) throws Exception {
		try {
			String orgguid=UserApi.get_org_id(session, orgName);
			if(!StringUtil.isEmpty(orgguid)&&!orgguid.equals(guid)) {
				return ExtJSResponse.successResWithData(false);
			}
		} catch(Exception e) {
			throw e;
		}
		return ExtJSResponse.successResWithData(true);
	}
	
	@Path("/bindQuota")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse bindQuota(@FormParam("orgName") String orgName,@FormParam("quota") String quota) throws Exception {
		OrgApi.setOrgQuota(session, orgName, quota);
		return ExtJSResponse.successResWithData(true);
	}
}
